<?php
/**
 * @file
 * "Callbacks" para la planeación de horarios.
 */

/**
 * @param  $accion Acción que el usuario desea hacer, los valores posibles son:
 *                 crear, editar y eliminar.
 * 
 * @return         Cadena de texto con el código HTML que se mostrará en el explorador.
 */
function planeacion_admin($accion = null)
{
    /* obtiene el identificador del usuario */
    global $user;
    $uid = $user->uid;

    /* ejecuta una acción, dependiendo del valor de la variable */    
    switch($accion)
    {
        /* muestra la información de la planeación actual */
        case 'actual':     return ver_planeacion($uid);
        
        /* información de las planeaciones anteriores */
        case 'anteriores': return "Planeacionees anteriores"; 

        /* editar los datos de la planeación */
        case 'editar':     return editar_planeacion($uid);

        /* elimina la información de la planeación del alumno */
        case 'eliminar':   return drupal_get_form('eliminar_planeacion_form');
        
        /* si no ocurre ninguna de las opciones anteriores regresa una cadena vacía */
        default:           return "";
    }
}

/**
 * Muestra la información de la planeación actual.
 * 
 * @param $uid Identificador del alumnos.
 * @return string Tabla con la información de la planeación actual.
 */
function ver_planeacion($uid)
{
    /* verifica si actualmente hay un periodo de pre-registro */
    $datos_periodo_actual = verifica_periodo_actual();
    genera_horarios($datos_periodo_actual);
    if(count($datos_periodo_actual) > 0)
    {
        if($upid = verifica_planeacion_actual($datos_periodo_actual['pid'], $uid))
        {
            /* encabezado de la tabla */
            $encabezado = array(array('data' => t('Clave de la UEA') , 'field' => 'u.clave'),
                                array('data' => t('Nombre de la UEA'), 'field' => 'u.nombre'),
                                array('data' => t('No. de créditos') , 'field' => 'u.creditos'),
                                array('data' => t('Horario') , 'field' => 'up.horario', 'sort'  => 'asc'));

            /* consulta SQL para obtener las UEAs planeadas en el periodo actual */
            $consulta = "SELECT u.clave, u.nombre, u.creditos, up.horario ".
                          "FROM {ueas_planeaciones} up, {ueas} u ".
                          "WHERE u.id_uea = up.id_uea AND up.id_planeacion = %d";            
            $consulta .= tablesort_sql($encabezado);
            
            /* arreglo para almacenar las filas de la tabla */
            $filas = array();

            /* obtiene las UEAs planeadas y las inserta en el arreglo $columnas*/
            $r = db_query($consulta, $upid);
            while($fila = db_fetch_object($r))
                $filas[] = array($fila->clave, $fila->nombre, $fila->creditos, $fila->horario);

            /* crea la tabla y regresa los datos */
            $salida .= theme_table($encabezado, $filas);

            return $salida;
        }
        else
        {
            /* mensaje de alerta, indica que no se ha creado una planeación */
            drupal_set_message(t("No haz creado una planeación de horario para el periodo actual.".
                                 " Si deseas hacerlo haz clic en el botón de abajo."),
                               "warning",
                               FALSE);

            /* crea el formulario que le permite al alumno crear una nueva planeación */
            return drupal_get_form('form_crear_planeacion', $datos_periodo_actual['pid'], $uid);
        }
    }

    return "No hay información que mostrar.";
}

/**
 * Controlador para editar las planeaciones.
 * 
 * @param $uid Identificador del usuario.
 */
function editar_planeacion($uid)
{
    /* verifica si actualmente hay un periodo de pre-registro */
    $datosp = verifica_periodo_actual();
    if(count($datosp) > 0)
    {
        if($upid = verifica_planeacion_actual($datosp['pid'], $uid))
        {
            /* muestra los detalles de la última planeación */
            return drupal_get_form('form_editar_planeacion', $upid, $datosp);
        }
        else
        {
            /* mensaje de alerta, indica que no se ha creado una planeación */
            drupal_set_message(t("No haz creado una planeación de horario para el periodo actual.".
                                 " Si deseas hacerlo haz clic en el botón de abajo."),
                               "warning",
                               FALSE);

            /* crea el formulario que le permite al alumno crear una nueva planeación */
            return drupal_get_form('form_crear_planeacion', $datosp['pid'], $uid);
        }
    }

    return "No se puede editar la planeación. El periodo ha finalizado.";
}

/**
 * Verifica si hay un periodo actual de pre-registro, y checa si está activo.
 * 
 * @return 0 No hay periodo actual de pre-registro.
 * @return p Existe un último periodo, pero el tiempo de pre-registro ha expirado.
 * @return   Si existe un periodo actual y se permiten pre-registros. Regresa un arreglo
 *           asociativo con información del periodo actual.
 */
function verifica_periodo_actual()
{
    $datosp = array
    (
        'creditos_maxtrim' => 50,
        'horas_periodo'    => 1.5,
        'pid'              => 2,
        'hora_libre'       => "14:00 - 15:00"
    );

    return $datosp;
}

/**
 * Verifica si el alumno ya ha creado una planeación de horario en el periodo actual.
 * 
 * @param  $pid Identificador del periodo actual.
 * @param  $uid Identificador del alumno.
 * 
 * @return 0    Si no existe una planeación del usuario en el periodo actual.
 * @return upid Si existe una planeación regresa el identificador de la planeación del
 *              usuario.
 */
function verifica_planeacion_actual($pid, $uid)
{
    /* ejecuta la consulta */
    $resultado = db_query("SELECT id_planeacion AS upid FROM {sph_planeaciones} ".
                          "WHERE id_periodo = %d AND id_alumno = %d",
                          $pid, $uid);
    
    /* verifica si hubo resultados */
    if(db_affected_rows($resultado))
    {
        $alumno = db_fetch_array($resultado);
        return $alumno['upid'];
    }
    else
        return 0;
}

/**
 * Formulario para crear una nueva planeación del usuario que hace la petición.
 * 
 * @ingroup forms
 * 
 * @param  $pid  Identificador del periodo actual.
 * @param  $uid  Identificador del usuario.
 * 
 * @return $form Arreglo asociativo con los elementos del formulario.
 */
function form_crear_planeacion($form_id, $pid, $uid)
{
    /* identificador del periodo actual, invisible en el formulario */
    $form['pid'] = array
    (
        '#type' => 'value',
        '#value' => $pid
    );

    /* identificador del alumno, invisible en el formulario */
    $form['uid'] = array
    (
        '#type' => 'value',
        '#value' => $uid
    );

    /* botón de crear */
    $form['crear-planeacion'] = array
    (
        '#type' =>        'submit',
        '#value' =>       "Crear planeación",
    );

    /* redirecciona a la sección de planeación */
    $form['#redirect'] = 'sph/planeacion/editar';

    return $form;
}

/**
 * Tareas a realizar cuando se usa el formulario para crear una nueva planeación.
 * 
 * @param $id   Identificador del formulario.
 * @param $form Arreglo asociativo con los campos y valores del formulario.
 */
function form_crear_planeacion_submit($id, &$form)
{
    $consulta = "INSERT INTO {sph_planeaciones} VALUES (NULL, %d, %d)";
    /* crea la nueva planeación para el alumno y escribe un mensaje de confirmación */
    if(db_query($consulta, $form['values']['pid'], $form['values']['uid']))
        drupal_set_message(t("Planeación creada correctamente. Ahora puedes agregar UEAs."),
                           'warning');
    else
        drupal_set_message(t("No se pudo crear la planeación."), 'error');
    
}

/*
 * Formulario para editar una planeación de horario.
 * 
 * @ingroup forms
 * 
 * @param $upid   Identificador de la planeación del usuario.
 * @param $datosp Información del periodo de planeación actual.
 */
 function form_editar_planeacion($form_id, $upid, $datosp)
 {
    $c = "(SELECT id_uea AS fid, clave, nombre, creditos, 'disponibles' AS region, ".
         "'00:00 - 00:00' AS horario FROM {ueas} WHERE id_uea NOT IN ".
         "(SELECT u.id_uea FROM {ueas} u, {ueas_planeaciones} up WHERE up.id_uea = u.id_uea AND up.id_planeacion = %d))".
         " UNION ".
         "(SELECT u.id_uea AS fid, u.clave AS clave, u.nombre AS nombre, ".
         "u.creditos AS creditos, 'planeadas' AS region, up.horario AS horario ".
         "FROM {ueas} u, {ueas_planeaciones} up WHERE up.id_uea = u.id_uea AND up.id_planeacion = %d) ORDER BY region DESC, nombre";
    $resultado = db_query($c, $upid, $upid);
    
    /* inicializa las regiones */
    $form['planeadas'] = array();
    $form['disponibles'] = array();

     /* información de las regiones */
    $regiones = array('planeadas'   => t("UEAs pre-registradas actualmente"),
                      'disponibles' => t("UEAs que puedes pre-registrar"));

    /* horarios disponibles */
    $horarios = genera_horarios($datosp);

    /* agrega los elementos al arreglo del formulario */
    while($uea = db_fetch_object($resultado))
    {
        $form[$uea->region][$uea->fid]['clave']    = array('#value'         => $uea->clave);
        $form[$uea->region][$uea->fid]['creditos'] = array('#value'         => $uea->creditos);
        $form[$uea->region][$uea->fid]['horario']  = array('#type'          => 'select',
                                                           '#default_value' => $uea->horario,
                                                           '#options'       => $horarios);
        $form[$uea->region][$uea->fid]['nombre']   = array('#value'         => $uea->nombre);
        $form[$uea->region][$uea->fid]['region']   = array('#type'          => 'select',
                                                           '#default_value' => $uea->region,
                                                           '#options'       => $regiones);
        $form[$uea->region][$uea->fid]['weight']   = array('#type'          => 'weight',
                                                           '#default_value' => 0);
    }

    /* datos que son pasados como parámetros */
    $form['datosp']   = array('#value' => $datosp  , '#type' => 'value');
    $form['upid']     = array('#value' => $upid    , '#type' => 'value');
    $form['regiones'] = array('#value' => $regiones, '#type' => 'value');
    
    /* indica si el la region está vacía */
    foreach($regiones as $region => $nombre_region)
        $form[$region]['vacio'] = array('#value' => empty($form[$region]), '#type' => 'value');

    /* agrega el botón de actualizar sólo si hay UEAs registradas o disponibles */
    if(count($form['disponibles']) || count($form['planeadas']))
        $form['actualizar'] = array('#type' => 'submit', '#value' => t('Actualizar planeación'));

    /* IMPORTANTE, no se anidan los elementos si no se agrega esta propiedad */
    $form['#tree'] = TRUE;

    return $form;
}

/**
 * Tema para el formulario de edición de planeaciones.
 * 
 * @ingroup themeable
 */
function theme_form_editar_planeacion($form)
{
    /* agrega la hoja de estilos */
    drupal_add_css(drupal_get_path('module', 'sph') .'/sph.css');
    
    /* añade los scripts JS necesarios */
    drupal_add_js(drupal_get_path('module', 'sph') .'/sph.js');

    /* crea las tablas */
    drupal_add_tabledrag('ueas', 'match', 'sibling', 'uea-region-select', 'uea-region-planeadas');
    drupal_add_tabledrag('ueas', 'order', 'sibling', 'uea-weight'       , 'uea-weight-planeadas');    
    drupal_add_tabledrag('ueas', 'match', 'sibling', 'uea-region-select', 'uea-region-disponibles');
    drupal_add_tabledrag('ueas', 'order', 'sibling', 'uea-weight'       , 'uea-weight-disponibles');

    $rows = array();
    $regiona = $form['regiones']['#value'][0];
    foreach($form['regiones']['#value'] as $region => $nombre_region)
    {
        if(isset($form['actualizar']) && ($region != 'planeadas'))
        {
            $rows[] = array('data' =>  array(array('data' => drupal_render($form['actualizar']),
                                                   'colspan' => 6,
                                                   'class' => "region",
                                                   'style' => "text-align: center")));
        }

        /* agrega el nombre de la region */
        $rows[] = array('data' =>  array(array('data' => $nombre_region,
                                               'colspan' => 6,
                                               'class' => "region")),
                        'class' => "region region-$region");

        $rows[] = array('data'  => array(array('data' => '<em>'. t('No hay UEAs en esta sección') .'</em>',
                                               'colspan' => 6)),
                        'class' => "region-message region-$region-message ".
                                   ($form[$region]['vacio']['#value'] ? "region-empty" : "region-populated"));

        /* procesa la información por regiones */
        foreach($form[$region] as $id_uea => $info_uea)
        {
            /* sólo los identificadores con número entero, es el identificador de la UEA */
            if(intval($id_uea))
            {
                /* información de cada UEA */
                $field = &$form[$region][$id_uea];
    
                /* añade clases especiales a los elementos para soportar el "drag and drop" */
                $field['region']['#attributes']['class'] = "uea-region-select uea-region-$region";
                $field['weight']['#attributes']['class'] = "uea-weight        uea-weight-$region";
            
                /* añade la UEA a las filas de la tabla */
                $row   = array();
                $row[] = drupal_render($field['clave']);
                $row[] = drupal_render($field['nombre']);
                $row[] = drupal_render($field['creditos']);
                $row[] = drupal_render($field['horario']);

                /* procesa los elementos sólo si hay más de una UEA disponible */
                if(isset($form['actualizar']))
                {
                    $row[] = drupal_render($field['region']);
                    $row[] = drupal_render($field['weight']);
                }
    
                /* añade a la fila la clase "draggeable" */
                $rows[] = array('data' => $row, 'class' => 'draggable');
            }
        }
    }

    /* cabecera de la tabla */
    $header = array(t('Clave de la UEA'), t('Nombre de la UEA'), t('No. de créditos'), t('Horario'));

    /* agrega los siguientes elementos al encabezado sólo si hay más de una UEA disponible */
    if(isset($form['actualizar']))
    {
        $header[] = t('Category');
        $header[] = t('Weight');
    }

    $output .= theme('table', $header, $rows, array('id' => 'ueas'));
    $output .= drupal_render($form);

    return $output;
}

/**
 * Procesamiento de la información de la edición de planeaciones.
 * 
 * @param $form       Arreglo asociativo con los elementos del formulario.
 * @param $form_state Arreglo asociativo con los valores de los campos del formulario
 *                    después de que se enviaron los datos.
 * 
 * @see form_editar_planeacion
 */
function form_editar_planeacion_submit($form, &$form_state)
{
    /* consultas para agregar y eliminar UEAs de la planeación del usuario */
    $sql_d = "DELETE FROM {ueas_planeaciones} WHERE id_uea = %d AND id_planeacion = %d";
    $sql_i = "INSERT INTO {ueas_planeaciones} VALUES (%d, %d, '%s')";
    $sql_u = "UPDATE {ueas_planeaciones} SET horario = '%s' WHERE id_planeacion = %d AND id_uea = %d";

    /* datos del periodo de pre-registro */
    $datosp = $form_state['values']['datosp'];
    
    /* identificador de la planeación */
    $upid = $form_state['values']['upid'];
    
    /* UEAs que se agregarán a la planeación */
    $ueas_nuevas = array();
    
    foreach($form['regiones']['#value'] as $region => $nombre_region)
    {
        /* verifica que el arreglo no esté vacío */
        if(count($form_state['values'][$region]))
        {
            foreach($form_state['values'][$region] as $id_uea => $info_uea)
            {
                /* categoría anterior */
                $categoria_anterior = $form[$region][$id_uea]['region']['#default_value'];
                
                /* nueva categoría */
                $categoria = $form_state['values'][$region][$id_uea]['region'];
                
                /* horario anterior */
                $horario_anterior = $form[$region][$id_uea]['horario']['#default_value'];

                /* nuevo horario */
                $horario = $form_state['values'][$region][$id_uea]['horario'];

                /* verifica si hubo un cambio de categoría */
                if($categoria != $categoria_anterior)
                {
                    /* UEA que debe ser eliminada */
                    if($categoria_anterior == 'planeadas')
                        db_query($sql_d, $id_uea, $upid);
    
                    /* Las UEAs nuevas se agregan más adelante */
                    else
                        $ueas_nuevas[] = array($id_uea, $horario);
                }
                
                /* UEAs que están en la planeación del usuario pero cambiaron de horario */
                else if(($categoria == 'planeadas') && ($horario_anterior != $horario))
                    db_query($sql_u, $horario, $upid, $id_uea);
            }
        }
    }
        
    /* agrega las UEAs nuevas */
    foreach($ueas_nuevas as $uea)
        db_query($sql_i, $uea[0], $upid, $uea[1]);

    drupal_set_message("Planeación actualizada correctamente", 'warning');
    
    /* redirecciona a la página de visualización del periodo actual */
    $form_state['redirect'] = 'sph/planeacion';
}

/**
 * Crea el elemento que permite seleccionar el horario.
 * 
 * @param  $datos Datos de la planeación y del usuario.
 * @return Array  Arreglo asociativo perteneciente a un campo de selección según el API de
 *                formularios de Drupal.
 */
function genera_horarios($datos)
{
    /* hora de inicio de la primera clase */
    $hora_inicio = 800;
    
    /* hora en que termina la última clase */
    $hora_fin = 2100;
    
    /* duración de cada clase */
    $duracion = floatval($datos['horas_periodo']) * 60;
    
    /* opciones para los horarios */
    $opciones = array();

    $hl = $datos['hora_libre'];
    
    /* convierte las hora inicial y final a números enteros */
    $hora_str = $hl[0].$hl[1].$hl[3].$hl[4];
    $horal_inicio = intval($hora_str);
    $hora_str = $hl[8].$hl[9].$hl[11].$hl[12];
    $horal_fin = intval($hora_str);
    
    $ignora = false;
    while($hora_inicio < $hora_fin)
    {
        $hora_fin_tmp = suma_hora($hora_inicio, $duracion);

        if($hl != "00:00 - 00:00")
        {            
            if($hora_fin_tmp <= $horal_inicio)
            {
                $hora = formato_intervalo_tiempo($hora_inicio, $hora_inicio = $hora_fin_tmp);
                $opciones[$hora] = $hora;
            }
            else if(($hora_inicio >= $horal_fin) && ($hora_fin_tmp <= $hora_fin))
            {
                $hora = formato_intervalo_tiempo($hora_inicio, $hora_inicio = $hora_fin_tmp);
                $opciones[$hora] = $hora;
            }

            else if(($hora_inicio <= $horal_inicio) && ($hora_fin_tmp >= $horal_fin))
                $hora_inicio = $horal_fin;
            
            else if(($hora_inicio > $horal_inicio) && ($hora_inicio < $horal_fin))
                $hora_inicio = $horal_fin;
            else
                $hora_inicio = $hora_fin_tmp;
        }
        else
        {
            if($hora_fin_tmp <= $hora_fin)
            {
                $hora = formato_intervalo_tiempo($hora_inicio, $hora_inicio = $hora_fin_tmp);
                $opciones[$hora] = $hora;
            }
        }
    }
    
    return $opciones;
}


/**
 * Suma a la hora $hora_inicio el número de minutos especificados en $d.
 * 
 * @param  $hora_inicio Hora inicial.
 * @param  $d           Cantidad de minutos que se suman.
 * @return string       Hora inicial con los $d minutos añadidos.
 */
function suma_hora($hora_inicio, $d)
{
    $inc = $hora_inicio % 100 + $d;
    $hora_inicio -= ($hora_inicio % 100);
    $hora = $hora_inicio + (intval(($inc)/60) * 100) + ($inc % 60);

    return $hora;
}

function formato_intervalo_tiempo($inicio, $fin)
{
    $mi = $inicio % 100;
    $mf = $fin % 100;
    $hi = intval($inicio/100);
    $hf = intval($fin/100);

    return (($hi < 10) ? '0'.$hi : $hi).':'.(($mi < 10) ? '0'.$mi : $mi).
           ' - '.
           (($hf < 10) ? '0'.$hf : $hf).':'.(($mf < 10) ? '0'.$mf : $mf);
}
?>
